package com.yss.system.service.impl;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yss.common.core.domain.TreeNode;
import com.yss.common.core.enums.YssStatusEnum;
import com.yss.system.mapper.SysUserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.yss.common.core.constant.UserConstants;
import com.yss.common.core.exception.BusinessException;
import com.yss.common.core.utils.SpringUtils;
import com.yss.common.core.utils.StringUtils;
import com.yss.common.datascope.annotation.DataScope;
import com.yss.common.security.utils.SecurityUtils;
import com.yss.system.api.domain.SysDept;
import com.yss.system.api.domain.SysRole;
import com.yss.system.api.domain.SysUser;
import com.yss.system.mapper.SysDeptMapper;
import com.yss.system.mapper.SysRoleMapper;
import com.yss.system.service.ISysDeptService;

/**
 * 部门管理 服务实现
 */
@Service("deptService")
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> implements ISysDeptService {
    @Autowired
    private SysDeptMapper deptMapper;

    @Autowired
    private SysRoleMapper roleMapper;
    @Autowired
    private SysUserMapper userMapper;

    /**
     * 查询部门管理数据
     *
     * @param dept 部门信息
     * @return 部门信息集合
     */
    @Override
    @DataScope
    public List<SysDept> selectDeptList(SysDept dept) {
        QueryWrapper<SysDept> wrapper = new QueryWrapper<>();
        wrapper.orderByAsc("PARENT_ID,ORDER_NUM");
        if (StringUtils.isNull(dept)) {
            this.list(wrapper);
        }
        if (StringUtils.isNotEmpty(dept.getDeptName())) {
            wrapper.like("DEPT_NAME", dept.getDeptName());
        }
        if (StringUtils.isNotEmpty(dept.getParentId())) {
            wrapper.eq("PARENT_ID", dept.getParentId());
        }
        if (null != dept.getStatus()) {
            wrapper.eq("STATUS", dept.getStatus());
        }
        if (StringUtils.isNotEmpty(dept.getId())) {
            List<String> list = this.queryDeptIds(dept.getId());
            list.add(dept.getId());
            wrapper.in("ID", list);
        } else {
            Object object = dept.getParams().get("dataScope");
            if (StringUtils.isNotNull(object)) {
                List<String> deptIds = (List<String>) object;
                if (StringUtils.isNotEmpty(deptIds)) {
                    wrapper.in("ID", deptIds);
                }
            }
        }
        return this.list(wrapper);
    }


    /**
     * 查询部门树结构信息
     *
     * @param dept 部门信息
     * @return 部门树信息集合
     */
    @Override
    @DataScope
    public List<TreeNode> selectDeptTreeList(SysDept dept) {
        List<TreeNode> list = new ArrayList<>();
        List<SysDept> depts = this.selectDeptList(dept);
        if (StringUtils.isEmpty(depts)) {
            return list;
        }
        List<String> tempList = depts.stream().map(SysDept::getId).collect(Collectors.toList());
        Set<String> set = new HashSet<>();
        for (SysDept sysDept : depts) {
            if (set.contains(sysDept.getParentId()) || tempList.contains(sysDept.getParentId())) {
                continue;
            }
            list.addAll(this.recursionTree(sysDept.getParentId(), depts));
            set.add(sysDept.getParentId());
        }
        return list;
    }

    private List<TreeNode> recursionTree(String id, List<SysDept> listSysDept) {
        List<TreeNode> list = new ArrayList<>();
        for (SysDept modular : listSysDept) {
            if (!id.equals(modular.getParentId())) {
                continue;
            }
            TreeNode treeNode = this.reportSysDeptToNode(modular);
            List<TreeNode> children = recursionTree(modular.getId(), listSysDept);
            treeNode.setChildren(children);
            list.add(treeNode);
        }
        return list;
    }

    /**
     * 将业务功能转化成TreeNode
     */
    private TreeNode reportSysDeptToNode(SysDept dept) {
        TreeNode node = new TreeNode();
        node.setId(dept.getId());
        node.setParentId(dept.getParentId());
        node.setLabel(dept.getDeptName());
        return node;
    }

    /**
     * 根据角色ID查询部门树信息
     *
     * @param roleId 角色ID
     * @return 选中部门列表
     */
    @Override
    public List<String> selectDeptListByRoleId(String roleId) {
        SysRole role = roleMapper.selectById(roleId);
        return deptMapper.selectDeptListByRoleId(roleId, role.isDeptCheckStrictly());
    }

    /**
     * 根据ID查询所有子部门（正常状态）
     *
     * @param deptId 部门ID
     * @return 子部门数
     */
    @Override
    public Long selectNormalChildrenDeptById(String deptId) {
        List<String> list = this.queryDeptIds(deptId);
        QueryWrapper<SysDept> wrapper = new QueryWrapper<>();
        wrapper.in("DEPT_ID", list);
        wrapper.eq("STATUS", "0");
        this.count(wrapper);
        return this.count(wrapper);
    }

    /**
     * 是否存在子节点
     *
     * @param deptId 部门ID
     * @return 结果
     */
    @Override
    public boolean hasChildByDeptId(String deptId) {
        QueryWrapper<SysDept> wrapper = new QueryWrapper<>();
        wrapper.eq("PARENT_ID", deptId);
        Long result = deptMapper.selectCount(wrapper);
        return result > 0;
    }

    /**
     * 查询部门是否存在用户
     *
     * @param deptId 部门ID
     * @return 结果 true 存在 false 不存在
     */
    @Override
    public boolean checkDeptExistUser(String deptId) {
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.eq("DEPT_ID", deptId);
        Long result = userMapper.selectCount(wrapper);
        return result > 0;
    }

    /**
     * 校验部门名称是否唯一
     *
     * @param dept 部门信息
     * @return 结果
     */
    @Override
    public boolean checkDeptNameUnique(SysDept dept) {
        String deptId = StringUtils.isNull(dept.getId()) ? "-1" : dept.getId();
        QueryWrapper<SysDept> wrapper = new QueryWrapper<>();
        wrapper.eq("DEPT_NAME", dept.getDeptName());
        wrapper.eq("PARENT_ID", dept.getParentId());
        SysDept info = deptMapper.selectOne(wrapper);
        if (StringUtils.isNotNull(info) && !info.getId().equals(deptId)) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 校验部门是否有数据权限
     *
     * @param deptId 部门id
     */
    @Override
    public void checkDeptDataScope(String deptId) {
        if (!SysUser.isAdmin(SecurityUtils.getUserId())) {
            SysDept dept = new SysDept();
            dept.setId(deptId);
            List<SysDept> depts = SpringUtils.getAopProxy(this).selectDeptList(dept);
            if (StringUtils.isEmpty(depts)) {
                throw new BusinessException("没有权限访问部门数据！");
            }
        }
    }

    /**
     * 新增保存部门信息
     *
     * @param dept 部门信息
     * @return 结果
     */
    @Override
    public int insertDept(SysDept dept) {
        SysDept info = this.getById(dept.getParentId());
        // 如果父节点不为正常状态,则不允许新增子节点
        if (null != info && YssStatusEnum.DELETED.getCode().equals(info.getStatus())) {
            throw new BusinessException("部门停用，不允许新增");
        }
        return deptMapper.insert(dept);
    }

    /**
     * 修改保存部门信息
     *
     * @param dept 部门信息
     * @return 结果
     */
    @Override
    public int updateDept(SysDept dept) {
        int result = deptMapper.updateById(dept);
        if (YssStatusEnum.NORMAL.getCode().equals(dept.getStatus())) {
            // 如果该部门是启用状态，则启用该部门的所有上级部门
            List<String> ids = this.queryParentDeptIds(dept.getId());
            UpdateWrapper<SysDept> wrapper = new UpdateWrapper<>();
            wrapper.in("ID", ids);
            SysDept sysDept = new SysDept();
            sysDept.setStatus(YssStatusEnum.NORMAL.getCode());
            this.update(sysDept, wrapper);
        }
        return result;
    }

    /**
     * 删除部门管理信息
     *
     * @param deptId 部门ID
     * @return 结果
     */
    @Override
    public int deleteDeptById(String deptId) {
        return deptMapper.deleteById(deptId);
    }

    /**
     * 递归查询所有下级部门ID集合
     *
     * @param id
     * @return
     * @throws Exception
     */
    public List<String> queryDeptIds(String id) {
        if (StringUtils.isBlank(id)) {
            throw new BusinessException("获取部门信息失败，请稍后重试！");
        }
        List<String> strList = new ArrayList<>();
        List<SysDept> list = this.list();
        recursionIds(id, strList, list);
        return strList;
    }

    private void recursionIds(String id, List<String> strList, List<SysDept> list) {
        for (SysDept sysDept : list) {
            if (!id.equals(sysDept.getParentId())) {
                continue;
            }
            strList.add(sysDept.getId());
            recursionIds(sysDept.getId(), strList, list);
        }
    }


    /**
     * 所有父级部门
     *
     * @param id
     * @return
     */
    public List<String> queryParentDeptIds(String id) {
        if (StringUtils.isBlank(id)) {
            throw new BusinessException("获取部门信息失败，请稍后重试！");
        }
        List<String> strList = new ArrayList<>();
        List<SysDept> list = this.list();
        SysDept dept = this.getById(id);
        strList.add(dept.getParentId());
        recursionParentIds(dept.getParentId(), strList, list);
        return strList;
    }

    private void recursionParentIds(String parentId, List<String> strList, List<SysDept> list) {
        for (SysDept sysDept : list) {
            if (parentId.equals(sysDept.getId())) {
                continue;
            }
            strList.add(sysDept.getId());
            recursionIds(sysDept.getParentId(), strList, list);
        }
    }

}
